package com.bcmusic.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.bcmusic.music.feign.MusicPermissionFeign;
import com.bcmusic.music.pojo.MusicPermission;
import com.bcmusic.order.dao.OrderCartMapper;
import com.bcmusic.order.dao.OrdersMapper;
import com.bcmusic.order.domain.cart.vo.OrderCartVO;
import com.bcmusic.order.domain.orders.CreateOrdersVO;
import com.bcmusic.order.pojo.OrderCart;
import com.bcmusic.order.pojo.OrderDetail;
import com.bcmusic.order.pojo.Orders;
import com.bcmusic.order.service.OrdersService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import entity.DateUtil;
import entity.IdWorker;
import entity.SmartBeanUtil;
import org.aspectj.bridge.MessageWriter;
import org.aspectj.weaver.ast.Or;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/****
 * @Author:admin
 * @Description:Orders业务层接口实现类
 * @Date 2019/6/14 0:16
 *****/
@Service
public class OrdersServiceImpl implements OrdersService {

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private OrderCartMapper orderCartMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private Environment env;
    @Autowired
    private MusicPermissionFeign musicPermissionFeign;


    /**
     * Orders条件+分页查询
     *
     * @param orders 查询条件
     * @param page   页码
     * @param size   页大小
     * @return 分页结果
     */
    @Override
    public PageInfo<Orders> findPage(Orders orders, int page, int size) {
        //分页
        PageHelper.startPage(page, size);
        //搜索条件构建
        Example example = createExample(orders);
        //执行搜索
        return new PageInfo<Orders>(ordersMapper.selectByExample(example));
    }

    /**
     * Orders分页查询
     *
     * @param page
     * @param size
     * @return
     */
    @Override
    public PageInfo<Orders> findPage(int page, int size) {
        //静态分页
        PageHelper.startPage(page, size);
        //分页查询
        return new PageInfo<Orders>(ordersMapper.selectAll());
    }

    /**
     * Orders条件查询
     *
     * @param orders
     * @return
     */
    @Override
    public List<Orders> findList(Orders orders) {
        //构建查询条件
        Example example = createExample(orders);
        //根据构建的条件查询数据
        return ordersMapper.selectByExample(example);
    }


    /**
     * Orders构建查询对象
     *
     * @param orders
     * @return
     */
    /**
     * OrderDetail构建查询对象
     * @param orderDetail
     * @return
     */

    /**
     * Orders构建查询对象
     * @param orders
     * @return
     */
    public Example createExample(Orders orders){
        Example example=new Example(Orders.class);
        Example.Criteria criteria = example.createCriteria();
        if(orders!=null){
            // 音乐订单id。
            if(!StringUtils.isEmpty(orders.getOrderId())){
                criteria.andEqualTo("orderId",orders.getOrderId());
            }
            // 被授权方编号。关联user表的user_number字段。
            if(!StringUtils.isEmpty(orders.getUserNumber())){
                criteria.andEqualTo("userNumber",orders.getUserNumber());
            }
            // 支付方式。（暂定）00默认为MB支付，01为第三方支付。
            if(!StringUtils.isEmpty(orders.getPaymentMethod())){
                criteria.andEqualTo("paymentMethod",orders.getPaymentMethod());
            }
            // 订单总额。订单总额 = 支付总额 + 优惠总额。
            if(!StringUtils.isEmpty(orders.getOrderAmount())){
                criteria.andEqualTo("orderAmount",orders.getOrderAmount());
            }
            // 优惠总额。
            if(!StringUtils.isEmpty(orders.getDiscountAmount())){
                criteria.andEqualTo("discountAmount",orders.getDiscountAmount());
            }
            // 支付总额。
            if(!StringUtils.isEmpty(orders.getPaymentAmount())){
                criteria.andEqualTo("paymentAmount",orders.getPaymentAmount());
            }
            // 音乐订单MB积分。即被授权方完成该订单可获得的MB积分回馈。
            if(!StringUtils.isEmpty(orders.getOrderMbPoint())){
                criteria.andEqualTo("orderMbPoint",orders.getOrderMbPoint());
            }
            // 音乐订单状态。0默认为待支付，1为已支付，2为已完成，-1为已取消，-2为已过期。被授权方支付后要确认到账才算完成该订单。订单超时未支付会过期。
            if(!StringUtils.isEmpty(orders.getValidStatus())){
                criteria.andEqualTo("validStatus",orders.getValidStatus());
            }
            // 提交时间。默认为订单提交时间。
            if(!StringUtils.isEmpty(orders.getCreateTime())){
                criteria.andEqualTo("createTime",orders.getCreateTime());
            }
            // 支付时间。即被授权方完成支付的时间。
            if(!StringUtils.isEmpty(orders.getPayTime())){
                criteria.andEqualTo("payTime",orders.getPayTime());
            }
            // 完成时间。即确认支付的账款到账/取消订单/订单超时过期的时间。
            if(!StringUtils.isEmpty(orders.getFinishTime())){
                criteria.andEqualTo("finishTime",orders.getFinishTime());
            }
        }
        return example;
    }


    /**
     * 将订单状态设置为未支付
     *
     * @param id
     */
    @Override
    public void unPay(Integer id) {
        Orders orders=new Orders();
        orders.setOrderId(id);
        orders.setValidStatus(-2);
        ordersMapper.updateByPrimaryKeySelective(orders);
    }

    /**
     * 修改Orders
     *
     * @param orders
     */
    @Override
    public void update(Orders orders) {
        ordersMapper.updateByPrimaryKey(orders);
    }

    /**
     * 增加Orders
     *
     * @param orders
     */
    @Override
    public void add(Orders orders) {
        ordersMapper.insert(orders);
    }

    /**
     * 根据ID查询Orders
     *
     * @param id
     * @return
     */
    @Override
    public Orders findById(Integer id) {
        return ordersMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询Orders全部数据
     *
     * @return
     */
    @Override
    public List<Orders> findAll() {
        return ordersMapper.selectAll();
    }

    /**
     * 创建订单
     * @param userNum
     * @param permissionIdList
     * @return
     */
    @Rollback
    @Override
    public CreateOrdersVO createOrder(String userNum, List<Integer> permissionIdList) {
        if(permissionIdList.size()==0){
            return null;
        }
        List<MusicPermission> data = musicPermissionFeign.getPermissionByIdList(permissionIdList).getData();
        //如果有无效的让用户刷新购物车重试
        for (int i = 0; i < data.size(); i++) {
            if(!data.get(i).getValidStatus().equals(1)){
                return null;
            }
        }
        List<OrderCart> list = redisTemplate.boundHashOps("orderCart" + userNum).multiGet(permissionIdList);
        BigDecimal totalMoney=new BigDecimal("0.00");
        for (int i = 0; i < list.size(); i++) {
            totalMoney.add(new BigDecimal(list.get(i).getTotalPrices()));
        }
        long id = idWorker.nextId();

        //这里没更新时间。。。后面填坑
        CreateOrdersVO order=new CreateOrdersVO();
        order.setDiscountAmount("0");
        order.setPaymentAmount(totalMoney.toString());
        order.setOrderAmount(totalMoney.toString());
        order.setOrderId(id);
        order.setUserNum(userNum);
        List<OrderCartVO> orderCartVOS = SmartBeanUtil.copyList(list, OrderCartVO.class);
        order.setOrderCartList(orderCartVOS);

        //将购物车列表放入redis中，设置过期时间30分钟，如果用户没有提交订单就自动删除。。暂时找不到方法对里面每一个hash设置过期时间
        //防止其上次有没有支付的订单
        redisTemplate.boundHashOps("unSubmitCart").delete(userNum);
        //放到未提交订单列表中，不删除购物车
        redisTemplate.boundHashOps("unSubmitCart").put(userNum,permissionIdList);
        redisTemplate.boundHashOps("unSubmitOrders").put(id,order);

        return order;
    }

    @Rollback
    @Override
    public Integer submitOrders(String userNum, Long orderId) {
        CreateOrdersVO ordersVO= (CreateOrdersVO) redisTemplate.boundHashOps("unSubmitOrders").get(orderId);
        //如果预提交的订单过期或者不是这个人的订单，返回失败
        if(ordersVO==null||!ordersVO.getUserNum().equals(userNum)){
            return 0;
        }
        Orders orders=new Orders();
        orders.setUserNumber(userNum);
        orders.setOrderAmount(ordersVO.getOrderAmount());
        orders.setDiscountAmount(ordersVO.getDiscountAmount());
        orders.setPaymentAmount(ordersVO.getPaymentAmount());

        ordersMapper.insertSelective(orders);
        //删除redis缓存的订单中的物品id
        List<Integer> permissionIdList= (List<Integer>) redisTemplate.boundHashOps("unSubmitCart").get(userNum);
        //将redis购物车中这些物品放入数据库中
        List<OrderCart> list = redisTemplate.boundHashOps("orderCart" + userNum).multiGet(permissionIdList);
        //这里不知道是不是selective //TODO 校验插入是否正确
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setOrderCartId(orders.getOrderId());
        }
        orderCartMapper.insertList(list);
        //删除reids中购物车对应的数据,一次性删除不知道为啥莫名其妙用不了
        for (int i = 0; i < permissionIdList.size(); i++) {
            redisTemplate.boundHashOps("orderCart" + userNum).delete(permissionIdList.get(i));
        }
        //订单放入redis中
        redisTemplate.boundHashOps("orders").put(orders.getOrderId(),orders);
        //订单放入延迟队列
        rabbitTemplate.convertAndSend(env.getProperty("mq.pay.queue.ordertimerdelay"), (Object) JSON.toJSONString(orders), new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //过期时间为0.5个小时
                message.getMessageProperties().setExpiration("1800000");
                return message;
            }
        });
        //redis 删除对应的购物车信息,一起删除莫名其妙用不了
        for (int i = 0; i < ordersVO.getOrderCartList().size(); i++) {
            redisTemplate.boundHashOps("orderCart" + userNum).delete(ordersVO.getOrderCartList().get(i).getPermissionId());
        }
        return orders.getOrderId();
    }

    @Override
    public void pay(Integer orderId) {
        Orders orders=new Orders();
        orders.setOrderId(orderId);
        //等后面版权存储了才算已经完成，这里只算已支付;
        orders.setValidStatus(1);
    }

    @Override
    public void finishOrder(Integer orderId) {
        Orders order=new Orders();
        order.setOrderId(orderId);
        order.setValidStatus(2);
        ordersMapper.updateByPrimaryKeySelective(order);
    }


//    /**
//     * 创建订单,如果购物车时间过去了，就会自动设置成当前时间，从当前时间
//     * 开始收费
//     *
//     * @param list
//     * @return
//     */
//    @Rollback//失败全部回滚
//    @Override
//    public Orders CreateOrders(List<OrderCart> list, String userNum) {
//        Orders orders = new Orders();
//        orders.setOrderNumber(String.valueOf(idWorker.nextId()));
//        orders.setAuthorizedNumber(userNum);
//        //购物车中对应id，由于没有对应字段，只能放到redis中。
//        List<Integer> idList = new ArrayList<>();
//        //每件商品应该付的钱列表
//        Map<Integer, String> perPay = new HashMap<>();
//        //每件打折的钱
//        Map<Integer,String>perDis=new HashMap<>();
//        //四舍五入保留两位小数
//        DecimalFormat df = new DecimalFormat("0.00");
//        //计算总金额
//        BigDecimal orderAmount = new BigDecimal(0);
//        for (int i = 0; i < list.size(); i++) {
//            //如果起始时间是今天以前就把时间调成今天
//            if (list.get(i).getAuthorizationStartTime().compareTo(new Date()) == -1) {
//                list.get(i).setAuthorizationStartTime(new Date());
//            }
//            int intevalDay = DateUtil.getIntevalDay(list.get(i).getAuthorizationStartTime(), list.get(i).getAuthorizationEndTime());
//            //我只想写一个+=。。。。。。
//            //这个加有毒。。。
//            BigDecimal perAmount=new BigDecimal(list.get(0).getPricePerDay()).multiply(new BigDecimal(String.valueOf(intevalDay)));
//
//            orderAmount = orderAmount.add(perAmount);
//            //生成订单的同时将redis中的购物车数据添加到数据库中,方便后面生成订单详情
//            int id = list.get(i).getOrderCartId();
//            perPay.put(id,df.format(perAmount.multiply(new BigDecimal("0.95"))));
//            perDis.put(id,df.format(perAmount.multiply(new BigDecimal("0.05"))));
//            idList.add(id);
//        }
//
//
//        //设置总金额，优惠金额，应付金额，目前写死9.5折
//        orders.setOrderAmount(df.format(orderAmount));
//        orders.setPaymentAmount(df.format(orderAmount.multiply(new BigDecimal("0.95"))));
//        orders.setDiscountAmount(df.format(orderAmount.multiply(new BigDecimal("0.05"))));
//        orders.setCreateTime(new Date());
//        orders.setValidStatus(0);
//        //TODO 再校验一次合法性，，，，
//        ordersMapper.insertSelective(orders);
//        //将订单对应发布信息列表放入redis缓存，方便后面生成购物车
//        redisTemplate.boundHashOps(userNum +"_orderItems").put(orders.getOrderId(), idList);
//        //每件商品付的价钱,结构不对，后面改
//        redisTemplate.boundHashOps(orders.getOrderId()).put(orders.getOrderId()+"_perPay",perPay);
//        //每件商品折扣价钱
//        redisTemplate.boundHashOps(orders.getOrderId()).put(orders.getOrderId()+"_perDis",perDis);
//        //将订单放入redis，方便定时任务查询支付状态（如果是数据库太耗费性能）
//        redisTemplate.boundHashOps("Order").put(orders.getOrderId(), orders);
//
//        //放入延迟队列
//        rabbitTemplate.convertAndSend(env.getProperty("mq.pay.queue.ordertimerdelay"), (Object) JSON.toJSONString(orders), new MessagePostProcessor() {
//            @Override
//            public Message postProcessMessage(Message message) throws AmqpException {
//                //过期时间为0.5个小时
//                message.getMessageProperties().setExpiration("1800000");
//                return message;
//            }
//        });
//        return orders;
//    }



}
